Re: Trying to get postgres to use an index - Mailing list pgsql-general
From | Joel Stevenson |
---|---|
Subject | Re: Trying to get postgres to use an index |
Date | |
Msg-id | p06110425bdb2fb527182@[192.168.0.9] Whole thread Raw |
In response to | Re: Trying to get postgres to use an index (Pierre-Frédéric Caillaud<lists@boutiquenumerique.com>) |
Responses |
Re: Trying to get postgres to use an index
|
List | pgsql-general |
At 10:11 PM +0100 11/6/04, Pierre-Frédéric Caillaud wrote: >>explain select notificationID from NOTIFICATION n, ITEM i where >>n.itemID = i.itemID; >> QUERY PLAN >> >>------------------------------------------------------------------------ >>------ >> Hash Join (cost=47162.85..76291.32 rows=223672 width=44) >> Hash Cond: ("outer".itemid = "inner".itemid) >> -> Seq Scan on notification n (cost=0.00..12023.71 rows=223671 >>width=48) >> -> Hash (cost=42415.28..42415.28 rows=741028 width=4) >> -> Seq Scan on item i (cost=0.00..42415.28 rows=741028 >>width=4) >> >>This query takes about 20 seconds to run. > > Well, you're joining the entire two >tables, so yes, the seq scan might be faster. > Try your query with enable_seqscan=0 so >it'll use an index scan and compare the times. > You may be surprised to find that the >planner has indeed made the right choice. > This query selects 223672 rows, are you surprised it's slow ? I'm not a SQL guru by any stretch but would a constrained sub-select be appropriate here? e.g. a simple test setup where each record in table test1 has a FK referenced to an entry in test: joels=# \d test Table "public.test" Column | Type | Modifiers --------+--------------+----------- id | integer | not null foo | character(3) | Indexes: "test_pkey" primary key, btree (id) joels=# \d test1 Table "public.test1" Column | Type | Modifiers ---------+---------+----------- id | integer | not null test_id | integer | Indexes: "test1_pkey" primary key, btree (id) "test1_test_id_idx" btree (test_id) Foreign-key constraints: "$1" FOREIGN KEY (test_id) REFERENCES test(id) ON DELETE CASCADE joels=# select count(*) from test; count ------- 10001 (1 row) joels=# select count(*) from test1; count ------- 10001 (1 row) joels=# explain select test_id from test1 t1, test t where t1.test_id = t.id; QUERY PLAN ------------------------------------------------------------------------ Hash Join (cost=170.01..495.05 rows=10002 width=4) Hash Cond: ("outer".test_id = "inner".id) -> Seq Scan on test1 t1 (cost=0.00..150.01 rows=10001 width=4) -> Hash (cost=145.01..145.01 rows=10001 width=4) -> Seq Scan on test t (cost=0.00..145.01 rows=10001 width=4) (5 rows) joels=# explain select test_id from test1 t1 where test_id in (select id from test where id = t1.test_id); QUERY PLAN ------------------------------------------------------------------------------ Seq Scan on test1 t1 (cost=0.00..15269.02 rows=5001 width=4) Filter: (subplan) SubPlan -> Index Scan using test_pkey on test (cost=0.00..3.01 rows=2 width=4) Index Cond: (id = $0) (5 rows) So with the subselect the query planner would use the primary key index on test when finding referencing records in the test1 table. Pierre, I seen the advice to use an additional where condition in certain cases to induce an index scan; how is this done? my 1.2 pennies, -Joel
pgsql-general by date: